package ch7.case7_1;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 使用开放调用（Open Call）改造ConfigurationManager
 * 所谓开放调用，就是一个方法在调用外部方法的时候不持有任何锁
 * 开放调用能够消除死锁产生的必要条件中的“持有并等待资源”
 *
 * 具体做法：使用线程安全的CopyOnWriteArraySet来替换原来的HashSet，
 * 这样update和load方法都不用使用synchronized代码块来保护临界区
 */

public enum ConfigurationManagerV2 {
   INSTANCE;

   protected final Set<ConfigEventListener> listeners;

   // 使用CopyOnWriteArraySet这个线程安全的Set接口实现类，替换掉原来普通的非线程安全的HashSet实现
    {
        listeners = new CopyOnWriteArraySet<ConfigEventListener>();
    }

    public Configuration load(String name) {
        Configuration cfg = loadConfigurationFromDB(name);
        // 加载配置数据的时候，还要把配置数据存到缓存中
        for (ConfigEventListener listener : listeners) {
            listener.onConfigLoaded(cfg);
        }
        return cfg;
    }

    private Configuration loadConfigurationFromDB(String name) {
        return null;
    }

    public void registerConfigEventListener(ConfigEventListener listener) {
        listeners.add(listener);
    }


    public void removeConfigEventListener(ConfigEventListener listener) {
        listeners.remove(listener);
    }


    public void update(String name, int newVersion, Map<String, String> properties) {
       for (ConfigEventListener listener : listeners) {
           listener.onConfigUpdated(name, newVersion, properties);
       }
    }
}
